package main

import "fmt"

//闭包
//1.闭包是一个函数，这个函数包含了他外部作用域的变量
//闭包=函数+外部变量的引用
func adder1() func(int) int {
	fmt.Println("addr1")
	var x int
	return func(y int) int {
		x += y
		return x
	}
}

//函数可以作为返回值，
//函数查找变量的顺序，先在自己内部找，找不到，往外层找
func adder2(x int) func(int) int {
	return func(y int) int {
		x += y
		return x
	}
}

func main() {

	/* 	变量f是一个函数并且它引用了其外部作用域中的x变量，
	   	此时f就是一个闭包。 在f的生命周期内，变量x也一直有效。
	   	闭包进阶示例1： */
	var f = adder1()
	fmt.Println(f(10)) //10
	fmt.Println(f(20)) //30
	fmt.Println(f(30)) //60

	f1 := adder1()
	fmt.Println(f1(40)) //40
	fmt.Println(f1(50)) //90

	ret := adder2(100)
	ret2 := ret(200)
	fmt.Println(ret2)
}
